package com.bestv.bsr.core.service.impl.jt;

import cn.hutool.core.util.RandomUtil;
import com.bestv.bsr.core.constants.AiSourceConstants;
import com.bestv.bsr.core.constants.ServiceCodeEnum;
import com.bestv.bsr.core.context.RecommendContext;
import com.bestv.bsr.core.entities.vo.RecDataVo;
import com.bestv.bsr.core.exceptions.ServiceException;
import com.bestv.bsr.core.properties.JTRecommendProperties;
import com.bestv.bsr.core.service.AbstractRecommendEngine;
import com.bestv.bsr.core.service.impl.jt.dto.JTRequestParam;
import com.bestv.bsr.core.service.impl.jt.dto.response.JTSearchResponseDto;
import com.bestv.bsr.core.service.impl.jt.dto.response.JTSimilarResponseDto;
import com.bestv.bsr.core.service.impl.jt.dto.response.JTTopicResponseDto;
import com.bestv.bsr.core.service.impl.jt.remote.JTRemoteService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 九天智能推荐
 *
 * @author taojiacheng
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class JTRecommendEngine extends AbstractRecommendEngine {

    private final JTRecommendProperties properties;
    private final JTRemoteService jtRemoteService;


    @Override
    public RecDataVo recommend(RecommendContext recommendContext) {
        List<String> itemCodes = recommendContext.getItemCodes();
        itemCodes.replaceAll(s -> properties.getCpid() + "|" + s);
        switch (recommendContext.getSceneId()) {
            case "1":
                // 节目播放详情页额推荐场景 对应九天 相似媒资推荐
                return similarRecommend(recommendContext);
            case "6":
                // 搜索页面场景 对应九天 搜索
                return searchRecommend(recommendContext);
            case "7":
                // 首页推荐场景 对应九天 主题推荐
                return topicDetailRecommend(recommendContext);
            default:
                throw new ServiceException(ServiceCodeEnum.SCENE_ID_NOT_SUPPORTED);
        }
    }

    @Override
    public void init(RecommendContext recommendContext) {

    }

    @Override
    public void validate(RecommendContext recommendContext) {
        String userAccount = recommendContext.getUserAccount();
        if (StringUtils.isEmpty(userAccount)) {
            log.error("userAccount is blank");
            throw new ServiceException(ServiceCodeEnum.USER_ACCOUNT_IS_BLANK);
        }
        String sceneId = recommendContext.getSceneId();
        List<String> sceneIds = properties.getSceneIds();
        if (sceneIds.contains(sceneId)) {
            log.error("sceneId: {} notSupported:", sceneId);
            throw new ServiceException(ServiceCodeEnum.SCENE_ID_NOT_SUPPORTED);
        }
    }


    /**
     * 榜单搜索
     */
    protected RecDataVo searchRecommend(RecommendContext recommendContext) {
        String itemType = recommendContext.getItemTypes().get(0);
        JTRequestParam.Context context = new JTRequestParam.Context();
        context.setAlbumid(recommendContext.getItemCodes());
        context.setChannel("1");
        JTRequestParam param = JTRequestParam.builder()
                .id(properties.getCpid() + RandomUtil.randomString(16))
                .userid(recommendContext.getUserAccount())
                .cpid(properties.getCpid())
                .context(context)
                // 榜单
                .rectype("ranklist")
                .sn(recommendContext.getMac())
                .numbers(recommendContext.getSize())
                // 好片榜
                .algoid("cmri_search_goodalblum")
                .build();
        JTSearchResponseDto responseDto = jtRemoteService.search(properties.getProvince(), param);
        return responseDto.convertToRecData(itemType);
    }

    /**
     * 相关性推荐
     */
    protected RecDataVo similarRecommend(RecommendContext recommendContext) {
        // tv_cms 中配置的推荐内容类型
        String itemType = recommendContext.getItemTypes().get(0);
        List<String> itemCodes = recommendContext.getItemCodes();
        String algoId = matchAlgoId(itemType);
        JTRequestParam.Context context = JTRequestParam.Context.builder()
                .albumid(recommendContext.getItemCodes())
                .channel("1")
                .build();
        JTRequestParam param = JTRequestParam.builder()
                .id(properties.getCpid() + RandomUtil.randomString(16))
                .userid(recommendContext.getUserAccount())
                .sn(recommendContext.getMac())
                .cpid(properties.getCpid())
                .type(algoId)
                .numbers(recommendContext.getSize())
                // 需要推荐相似媒资id列表
                .albumids(itemCodes)
                .context(context)
                .build();
        JTSimilarResponseDto responseDto = jtRemoteService.similarVideo(properties.getProvince(), param);
        // 处理返回结果
        return responseDto.convertToRecData(itemType);
    }

    /**
     * 主题推荐
     */
    protected RecDataVo topicDetailRecommend(RecommendContext recommendContext) {
        // tv_cms 中配置的推荐内容类型
        String itemType = recommendContext.getItemTypes().get(0);
        // 匹配配置到AlgoId
        String algoId = matchAlgoId(itemType);
        JTRequestParam.Context context = JTRequestParam.Context.builder()
                .channel("1")
                .albumid(recommendContext.getItemCodes())
                .build();
        JTRequestParam.Positions position = JTRequestParam.Positions.builder()
                .build();
        List<JTRequestParam.Positions> positions = Collections.singletonList(position);
        // 推荐主题详情
        JTRequestParam params = JTRequestParam.builder()
                .id(properties.getCpid() + RandomUtil.randomString(16))
                .rectype(properties.getTopicRecType())
                .userid(recommendContext.getUserAccount())
                .sn(recommendContext.getMac())
                .cpid(properties.getCpid())
                .context(context)
                .positions(positions)
                .numbers(recommendContext.getSize())
                .algoid(algoId)
                .build();
        JTTopicResponseDto responseDto = jtRemoteService.recommendTopicDetail(properties.getProvince(), params);
        return responseDto.convertToRecData(itemType);
    }

    /**
     * 通过besTV itemType 匹配 九天 AlgoId
     *
     * @param itemType itemType
     * @return AlgoId
     */
    protected String matchAlgoId(String itemType) {
        Map<String, String> itemTypeMap = properties.getItemTypeMap();
        String algoId = itemTypeMap.get(itemType);
        if (StringUtils.isEmpty(algoId)) {
            log.error("itemType not supported:{} ", itemType);
            throw new ServiceException(ServiceCodeEnum.ITEM_TYPES_NOT_SUPPORTED);
        }
        return algoId;
    }


    @Override
    protected List<String> addSupportedAiSource() {
        return Arrays.asList(AiSourceConstants.AI_SOURCE_JIU_TIAN,
                AiSourceConstants.AI_SOURCE_ANYD_JIUTIAN);
    }
}
